package com.chen.module.testproducerconsumer;

import android.util.Log;

import java.util.PriorityQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * create by chen on 2020/3/25 17:16
 * Email:chenshaopeng90@hotmail.com
 */
public class CenterControl {
    private static final String TAG = CenterControl.class.getName();
    private int queueSize = 10;
    private LinkedBlockingQueue<MessageBean> queue = new LinkedBlockingQueue<MessageBean>(queueSize);
    private LinkedBlockingQueue<MessageBean> queue2 = new LinkedBlockingQueue<MessageBean>(queueSize);
    private Lock lock = new ReentrantLock();
    private Condition actionCondition = lock.newCondition();
    private Condition actionCondition2 = lock.newCondition();
    private Consumer consumerThread;
    private Consumer2 consumerThread2;

    private static CenterControl INSTANCE;

    public CenterControl() {
        consumerThread = new Consumer();
        consumerThread.start();

//        consumerThread2 = new Consumer2();
//        consumerThread2.start();
    }
    public static CenterControl getInstance() {
        if (INSTANCE == null) {
            INSTANCE = new CenterControl();
        }
        return INSTANCE;
    }

    class Consumer extends Thread{
        @Override
        public void run() {
            while (true) {
                lock.lock();
                try {
                    System.out.println("begin take.......");

                    MessageBean poll = queue.take();
                    System.out.println("after take.......");

                    handlerMessageBean(poll);
                    actionCondition.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
        }
    }


    class Consumer2 extends Thread{
        @Override
        public void run() {
            while (true) {
                lock.lock();
                try {
//                    Log.e(TAG, "2 begin take.......");
                    System.out.println("2 begin take.......");

                    MessageBean poll = queue2.take();
//                    Log.e(TAG, "2 after take.......");
                    System.out.println("2 after take.......");

                    handlerMessageBean2(poll);

                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
        }

    }

    private void handlerMessageBean(final MessageBean msg) {

//        Log.e(TAG, "handlerMessageBean.......id: " + msg.getId());
        System.out.println("handlerMessageBean.......id: " + msg.getId());
        weekUpThread();
    }

    private void handlerMessageBean2(final MessageBean msg) {

//        Log.e(TAG, "2 handlerMessageBean.......id: " + msg.getId());
        System.out.println("2 handlerMessageBean.......id: " + msg.getId());

    }

    /**
     * 顺序任务（任务执行完成，唤醒线程，再执行下一个任务）
     * @param msg
     */
    public void putMsg(MessageBean msg) {
//        Log.e(TAG, "putMsg.......id: " + msg.getId());
        System.out.println("putMsg.......id: " + msg.getId());
        try {
            queue.put(msg);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     *  并列执行任务
     * @param msg
     */
    public void putMsg2(MessageBean msg) {
//        Log.e(TAG, "2 putMsg.......id: " + msg.getId());
        System.out.println("2 putMsg.......id: " + msg.getId());

        try {
            queue2.put(msg);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void weekUpThread() {
//        Log.e(TAG, "weekUpThread.......");
        System.out.println("weekUpThread.......");

        new Thread(new Runnable() {
            @Override
            public void run() {
                lock.lock();
                actionCondition.signal();//唤醒线程Consumer，线程Consumer恢复执行
                lock.unlock();
            }
        }).start();
    }


    public void weekUpThread2() {
        Log.e(TAG, "2 weekUpThread.......");
        new Thread(new Runnable() {
            @Override
            public void run() {
                lock.lock();
                actionCondition2.signal();//唤醒线程Consumer，线程Consumer恢复执行
                lock.unlock();
            }
        }).start();
    }
}
